﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace landlord2lib
{
    public class CardGroupProgressPair : CardGroup
    {
        public CardGroupProgressPair(Card[] cards)
        {
            m_cards = cards;
        }

        public override bool IsValid()
        {
            try
            {
                if (m_cards.Length < 6 || m_cards.Length % 2 != 0) return false;
                foreach (Card card in m_cards) card.Reset();

                List<Card> jokerCards = new List<Card>();
                List<Card>[] normalCards = new List<Card>[(int)CardPoint.CardA + 1];
                int start = 99;
                int end = -1;
                foreach (Card card in m_cards)
                {
                    if (card.IsJoker) jokerCards.Add(card);
                    else
                    {
                        if (normalCards[(int)card.ComparePoint] == null) normalCards[(int)card.ComparePoint] = new List<Card>();
                        normalCards[(int)card.ComparePoint].Add(card);
                        if (start > (int)card.ComparePoint) start = (int)card.ComparePoint;
                        if (end < (int)card.ComparePoint) end = (int)card.ComparePoint;
                    }
                }
                for (int i = start; i <= end; i++)
                {
                    if (normalCards[i] == null) normalCards[i] = new List<Card>();
                    for (int j = normalCards[i].Count; j < 2; j++)
                    {
                        if (jokerCards.Count == 0) return false;
                        Card joker = jokerCards[0];
                        jokerCards.RemoveAt(0);
                        joker.ComparePoint = (CardPoint)i;
                        normalCards[i].Add(joker);
                    }
                }
                if (jokerCards.Count % 2 != 0) return false;
                while (jokerCards.Count > 0 && end < (int)CardPoint.CardA)
                {
                    end++;
                    if (normalCards[end] == null) normalCards[end] = new List<Card>();
                    for (int j = 0; j < 2; j++)
                    {
                        if (jokerCards.Count == 0) break;
                        Card joker = jokerCards[0];
                        jokerCards.RemoveAt(0);
                        joker.ComparePoint = (CardPoint)end;
                        normalCards[end].Add(joker);
                    }
                }
                while (jokerCards.Count > 0 && start > (int)CardPoint.Card3)
                {
                    start--;
                    if (normalCards[start] == null) normalCards[start] = new List<Card>();
                    for (int j = 0; j < 2; j++)
                    {
                        if (jokerCards.Count == 0) break;
                        Card joker = jokerCards[0];
                        jokerCards.RemoveAt(0);
                        joker.ComparePoint = (CardPoint)start;
                        normalCards[start].Add(joker);
                    }
                }
                for (int i = start; i <= end; i++)
                {
                    if (normalCards[i] == null || normalCards[i].Count != 2) return false;
                }
                return true;
            }
            catch
            {
                return false;
            }
        }

        public override int CompareTo(CardGroup other)
        {
            try
            {
                if (other is CardGroupProgressPair)
                {
                    CardGroupProgressPair o = (CardGroupProgressPair)other;
                    if (m_cards.Length != o.m_cards.Length) return -1;
                    return GetCompareCard().CompareTo(o.GetCompareCard());
                }
                else return -1;
            }
            catch
            {
                return 0;
            }
        }

        private Card GetCompareCard()
        {
            Card cardMax = null;
            foreach (Card card in m_cards)
            {
                if (cardMax == null) cardMax = card;
                else if (card.CompareTo(cardMax) > 0) cardMax = card;
            }
            return cardMax;
        }

        public static HintCardCollection Hint(Card[] handCards, CardGroupProgressPair lastGroup)
        {
            HintCardCollection result = new HintCardCollection();
            try
            {
                CardStack stack = new CardStack(handCards);
                int count = lastGroup.Cards.Length / 2;
                CardPoint minPt = (CardPoint)((int)lastGroup.GetCompareCard().ComparePoint - count + 1);

                Dictionary<int, List<Card>> dict = new Dictionary<int, List<Card>>();
                for (int pt = (int)minPt + 1; pt <= (int)CardPoint.CardA; pt++)
                {
                    if (stack[pt].Count == 2)
                    {
                        List<Card> cards = new List<Card>();
                        for (int i = 0; i < 2; i++) cards.Add(stack[pt][i]);
                        dict.Add((int)cards[0].Point, cards);
                    }
                }

                for (int pt = (int)minPt + 1; pt <= (int)CardPoint.CardA; pt++)
                {
                    bool allHave = true;
                    for (int c = 0; c < count; c++)
                    {
                        if (!dict.ContainsKey(pt + c))
                        {
                            allHave = false;
                            break;
                        }
                    }
                    if (allHave)
                    {
                        List<Card> cards = new List<Card>();
                        for (int c = 0; c < count; c++) cards.AddRange(dict[pt + c]);
                        result.AddHint(cards.ToArray());
                    }
                }

                return result;
            }
            catch
            {
                return result;
            }
        }
    }
}
